All files / web/src/app/api/admin/blog/[slug] route.ts

0% Statements 0/89
0% Branches 0/1
0% Functions 0/1
0% Lines 0/89

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90                                                                                                                                                                                   
import fs from 'fs'
import path from 'path'
import matter from 'gray-matter'
import { NextResponse } from 'next/server'
import { withAuth } from '@/lib/auth/withAuth'

const postsDirectory = path.join(process.cwd(), 'content', 'blog')

/**
 * PATCH /api/admin/blog/[slug]
 *
 * Update blog post frontmatter fields (featured, heroCrop, heroPrompt).
 */
export const PATCH = withAuth(
  async (request, { params }) => {
    const { slug } = (await params) as { slug: string }

    const filePath = path.join(postsDirectory, `${slug}.md`)
    if (!fs.existsSync(filePath)) {
      return NextResponse.json({ error: 'Post not found' }, { status: 404 })
    }

    let body: {
      featured?: boolean
      heroCrop?: string
      heroPrompt?: string
      heroType?: string
      heroStoryId?: string
      heroComponentId?: string
    }
    try {
      body = await request.json()
    } catch {
      return NextResponse.json({ error: 'Invalid JSON' }, { status: 400 })
    }

    const fileContents = fs.readFileSync(filePath, 'utf8')
    const { data, content } = matter(fileContents)

    if (typeof body.featured === 'boolean') {
      data.featured = body.featured
    }
    if (typeof body.heroCrop === 'string') {
      data.heroCrop = body.heroCrop
    }
    if (typeof body.heroPrompt === 'string') {
      if (body.heroPrompt.trim()) {
        data.heroPrompt = body.heroPrompt.trim()
      } else {
        delete data.heroPrompt
      }
    }
    if (typeof body.heroType === 'string') {
      if (body.heroType.trim()) {
        data.heroType = body.heroType.trim()
      } else {
        delete data.heroType
      }
    }
    if (typeof body.heroStoryId === 'string') {
      if (body.heroStoryId.trim()) {
        data.heroStoryId = body.heroStoryId.trim()
      } else {
        delete data.heroStoryId
      }
    }
    if (typeof body.heroComponentId === 'string') {
      if (body.heroComponentId.trim()) {
        data.heroComponentId = body.heroComponentId.trim()
      } else {
        delete data.heroComponentId
      }
    }

    const updated = matter.stringify(content, data)
    fs.writeFileSync(filePath, updated, 'utf8')

    return NextResponse.json({
      slug,
      featured: data.featured ?? false,
      heroCrop: data.heroCrop ?? null,
      heroPrompt: data.heroPrompt ?? null,
      heroType: data.heroType ?? null,
      heroStoryId: data.heroStoryId ?? null,
      heroComponentId: data.heroComponentId ?? null,
    })
  },
  { role: 'admin' }
)